package main

import (
	"fmt"
	"reflect"
	"sync/atomic"
	"unsafe"
)

type Tst struct {
	Str string
}

type Test struct {
	A    uint16
	Arr  [5]byte `json:"abc"`
	Bits []byte
	Ints [3]int
	S    string
	Tst  Tst
}

type MyValue struct {
	Typ_ *MyValue
	Ptr  unsafe.Pointer
}

func GetAddr(v *reflect.Value) unsafe.Pointer {
	return (*(*MyValue)(unsafe.Pointer(v))).Ptr
}

func main() {

	var b atomic.Bool

	b.Store(false)

	fmt.Println(b.CompareAndSwap(false, true), b.Load())
	fmt.Println(b.CompareAndSwap(true, false), b.Load())
	fmt.Println(b.CompareAndSwap(true, false), b.Load())
	return

	t := []Test{{Bits: make([]byte, 10)}}

	// t.Arr[0] = 1
	// t.Bits = make([]byte, 10, 20)

	tp := reflect.TypeOf(t)

	fmt.Println("tp.Kind =", tp.Kind())

	if tp.Kind() == reflect.Slice {
		fmt.Println("process slice")
		et := tp.Elem()
		fmt.Println("et = ", et.Kind(), et.Name())
	} else if tp.Kind() == reflect.Ptr {
		fmt.Println("tp is ptr")
		tp = tp.Elem()
	}

	tv := reflect.ValueOf(&t)

	vv := tv
	if tv.Kind() == reflect.Ptr {
		fmt.Println("value is ptr")
		vv = tv.Elem()
	}

	for i := 0; i < vv.NumField(); i++ {
		// tp.FieldByIndex()
		fld := vv.Field(i)
		fld_tp := tp.Field(i)

		fmt.Printf("%d, %#v, size = %d, kind = %v \n", i, fld.Kind(), fld.Type().Size(), fld.Kind())

		if fld.Kind() == reflect.Slice || fld.Kind() == reflect.Array {
			fmt.Printf("%v cap = %d, len = %d, addr = %v elelType = %v \n", fld.Kind(), fld.Cap(), fld.Len(), GetAddr(&fld), fld_tp.Type.Elem().Kind())
		}

		// if fld_tp.Name == "Arr" {
		// 	fmt.Println("set 12******************* ", GetAddr(&fld))
		// 	// fld.SetUint(16)
		// }
	}

	var ps []byte

	ptr := unsafe.Pointer(&ps)
	// pps = (*[]byte)(ptr)

	// arr := []byte{1, 2, 3, 4, 5}
	for i := 0; i < 10; i++ {
		*((*[]byte)(ptr)) = append((*((*[]byte)(ptr))), byte(i))
	}

	var arr [5]byte
	pa := unsafe.Pointer(&arr)
	pap := (*[10000000]byte)(pa)

	copy((*pap)[:5], ps)

	// ptr := unsafe.Pointer(&arr)

	fmt.Println("ps = ", ps, arr)
}
